#include <stdio.h>

#include "cbit.h"
#include "cdes.h"


void cdes3_encrypt(const unsigned char *plaintext, unsigned char *ciphertext,
                         const unsigned char *key) {
	const unsigned char *k1 = NULL, *k2 = NULL, *k3 = NULL;
	unsigned char tmp_buf[8];

	if(key != NULL) {
		k1 = key;
		k2 = key + 8;
		k3 = k1;
	}

    cdes_encrypt(plaintext, ciphertext, k1);
	cdes_decrypt(ciphertext, tmp_buf, k2);
	cdes_encrypt(tmp_buf, ciphertext, k3);
    return;
}

void cdes3_decrypt(const unsigned char *ciphertext, unsigned char *plaintext,
                         const unsigned char *key) {
	const unsigned char *k1 = NULL, *k2 = NULL, *k3 = NULL;
	unsigned char tmp_buf[8];           

	if(key != NULL) {
		k1 = key;
		k2 = key + 8;
		k3 = k1;
	}
	
	cdes_decrypt(ciphertext, plaintext, k3);
	cdes_encrypt(plaintext, tmp_buf, k2);
	cdes_decrypt(tmp_buf, plaintext, k1); 
    return;
}

void cdes3_ecb_encrypt(const unsigned char *plaintext, unsigned char *ciphertext,
                      const unsigned char *key, int size) {
    int i =0;

    while(i < size) {
        cdes3_encrypt(&plaintext[i], &ciphertext[i], key);
        i = i + 8;
    }

    return;
}


void cdes3_ecb_decrypt(const unsigned char *ciphertext, unsigned char *plaintext,
                  const unsigned char *key, int size) {
    int i = 0;

    while(i < size) {
        cdes3_decrypt(&ciphertext[i], &plaintext[i], key);
        i = i + 8;
    }

    return;
}


void cdes3_cbc_encrypt(const unsigned char *plaintext, unsigned char *ciphertext,
                      const unsigned char *key, int size) {
    unsigned char temp[8];
    int i;

    cdes3_encrypt(&plaintext[0], &ciphertext[0], key);

    i = 8;
    while(i < size) {
        cbit_xor(&plaintext[i], &ciphertext[i - 8], temp, 64);
        cdes3_encrypt(temp, &ciphertext[i], NULL);
        i = i + 8;
    }

    return;
}


void cdes3_cbc_decrypt(const unsigned char *ciphertext, unsigned char *plaintext,
                  const unsigned char *key, int size) {
    unsigned char temp[8];
    int i;

    cdes3_decrypt(&ciphertext[0], &plaintext[0], key);

    i = 8;
    while(i < size) {
        cdes3_decrypt(&ciphertext[i], temp, NULL);
        cbit_xor(&ciphertext[i - 8], temp, &plaintext[i], 64);
        i = i + 8;
    }

    return;
}

